package service;

import java.util.Date;

import model.Match;
import model.User;

import org.springframework.transaction.annotation.Transactional;

import exceptions.MatchRestrictionException;

/**
 * Interface for MatchService.
 * @author Andre Melo
 * @author Marcus Leite 
 * @author Sergio Danilo
 *
 */
@Transactional
public interface MatchService {

	/**
	 * Get the user's number of losses in the league
	 * @param userId The ID of the user
	 * @param leagueId The ID of the league
	 * @return The number of losses of the user
	 */
	 Integer getNumberOfPlayerMatches(Integer userId, Integer leagueId);

	/**
	 * Get the number of league of the match
	 * @param leagueId The ID of the league
	 * @return The number of league
	 */
	 Integer getNumberOfLeagueMatches(Integer leagueId);

	/**
	 * Adds result to the match with league, date, winner and loser 
	 * as attributes 
	 * @param leagueId The ID of the league
	 * @param date The date of the match
	 * @param idWinner The ID of the winner
	 * @param idLoser The ID of the loser
	 * @return The ID of the match
	 * @throws MatchRestrictionException
	 */
	 Integer addMatchResult(Integer leagueId, Date date, Integer idWinner, Integer idLoser) throws MatchRestrictionException;

	/**
	 * Delete all existing matchs
	 */
	 void deleteAll();
	
	/**
	 * Get the winner of the macth 
	 * @param matchId The ID of the match
	 * @return The match's winner
	 */
	 User getMatchWinner(Integer matchId);
	
	/**
	 * Get the loser of the macth 
	 * @param matchId The ID of the match
	 * @return The match's loser
	 */
	 User getMatchLoser(Integer matchId);
	
	/**
	 * Get the user's number of wins in the league
	 * @param userId The ID of the user
	 * @param leagueId The ID of the league
	 * @return The number of wins of the user
	 */
	 Integer getNumberOfWins( Integer userId, Integer leagueId);
	
	/**
	 * Get the user's number of losses in the league
	 * @param userId The ID of the user
	 * @param leagueId The ID of the league
	 * @return The number of losses of the user
	 */
	 Integer getNumberOfLosses( Integer userId, Integer leagueId);

	/**
	 * Get match by the league's ID and the index that was created
	 * @param leagueId The ID of the league
	 * @param matchIndex The index of the match
	 * @return The required match
	 * @throws MatchRestrictionException
	 */
	 Integer getMatch(Integer leagueId, Integer index) throws MatchRestrictionException;


	/**
	 * Get match by the league's ID, the user's ID and the index that was created
	 * @param userId The ID of the user
	 * @param leagueId The ID of the league
	 * @param index The index of the match
	 * @return The required match
	 * @throws MatchRestrictionException
	 */
	 Integer getMatch(Integer userId, Integer leagueId, Integer index) throws MatchRestrictionException;

	/**
	 * Get the length of the macth 
	 * @param matchId The ID of the match
	 * @return The match's length
	 */
	 Integer getMatchLength(Integer matchId);

	/**
	 * Get the score of the macth 
	 * @param matchId The ID of the match
	 * @return The match's score
	 */
	 Integer getMatchScore(Integer matchId);

	/**
	 * Get the longest run for loser of the match
	 * @param matchId The ID of the match
	 * @return The match's longest run for loser
	 */
	 Integer getMatchLongestRunForLoser(Integer matchId);
	
	/**
	 * Get the longest run for winner of the match
	 * @param matchId The ID of the match
	 * @return The match's longest run for winner
	 */
	 Integer getMatchLongestRunForWinner(Integer matchId);

	/**
	 * Adds result to the match with league, date, winner and loser as attributes 
	 * @param leagueId The ID of the league
	 * @param date The date of the match
	 * @param idWinner The ID of the winner
	 * @param idLoser The ID of the loser
	 * @return The ID of the match
	 * @throws MatchRestrictionException
	 */
	 Integer addMatchResult(Integer leagueId, Date date,
			Integer idWinner, Integer idLoser, Integer length, Integer score,
			Integer longestRunForWinner, Integer longestRunForLoser) throws MatchRestrictionException;
	
	/**
	 * Update match result with new received attributes.
	 * @param matchId The ID of the match
	 * @param date The date of the match
	 * @param idWinner The winner of the match
	 * @param idLoser The loser of the match
	 * @param length The length of the match
	 * @param score The score of the match
	 * @param longestRunForWinner The longest run for winner of the match
	 * @param longestRunForLoser The longest run for loser of the match
	 * @throws MatchRestrictionException
	 */
	 void updateMatchResult(Integer matchId, Date date,
			Integer idWinner, Integer idLoser, Integer length, Integer score,
			Integer longestRunForWinner, Integer longestRunForLoser) throws MatchRestrictionException;

	/**
	 * Remove the match by the ID
	 * @param matchId The ID of the removed match
	 */
	 void deleteMatch(Integer matchId);

	/**
	 * Get the match by the date that was played
	 * @param leagueId The ID of the league
	 * @param mdStart The match date start  
	 * @param mdEnd The match date end
	 * @param matchIndex The index of the match
	 * @return The required match
	 * @throws MatchRestrictionException
	 */
	 Integer getMatchByDate(Integer leagueId, Date mdStart, Date mdEnd, Integer index)  throws MatchRestrictionException;
	
	/**
	 * Get the match by the date that was played
	 * @param userId The ID of the user
	 * @param leagueId The ID of the league
	 * @param mdStart The match date start  
	 * @param mdEnd The match date end
	 * @param matchIndex The index of the match
	 * @return The required match
	 * @throws MatchRestrictionException
	 */
	 Integer getMatchByDate(Integer userId, Integer leagueId, Date mdStart, Date mdEnd, Integer index) throws MatchRestrictionException;

	/**
	 * Get the match date
	 * @param matchId The ID of the match
	 * @return The match date
	 */
	 Date getMatchDate(Integer matchId);

	/**
	 * Get the string format for the match result.
	 * @param userId The ID of the user
	 * @param leagueId The ID of the league
	 * @param index The index of the index
	 * @return The string format for the match result
	 * @throws MatchRestrictionException
	 */
	 String getMatchAsString(Integer userId, Integer leagueId, Integer index) throws MatchRestrictionException;
	
	/**
	 * Updates the match
	 * @param match The match that will be updated 
	 */
	 void update(Match match);

	/**
	 * Set the user service attribute
	 * @param leagueService The new user service attribute
	 */
	 void setUserService(UserService userService);

	/**
	 * Set the league service attribute
	 * @param leagueService The new league service attribute
	 */
	 void setLeagueService(LeagueService leagueService);

	/**
	 * Save the match in persistence
	 * @param match The match attribute
	 * @return The ID of the match
	 */
	 Integer save(Match match);

	/**
	 * @return The user service attribute
	 */
	 UserService getUserService();

	/**
	 * Returns league service attribute
	 * @return League service attribute
	 */
	 LeagueService getLeagueService();

	/**
	 * Find the match by ID
	 * @param id The ID of the match
	 * @return The required match 
	 */
	 Match findById(Integer id);
}
